#include <FastLED.h>

#define LED_PIN  4

#define COLOR_ORDER GRB
#define CHIPSET     WS2813

#define BRIGHTNESS 60
boolean isAvailable = false;
#define TARGET_LED 0xE0
#define CLEAR 0XE1
#define SOLID 0XE2
#define GBRIGHTNESS 0xE3

#define NUM_LEDS (kMatrixWidth * kMatrixHeight)
const uint8_t kMatrixWidth = 32;
const uint8_t kMatrixHeight = 16;
char serialRead;
boolean isStart = false;
unsigned char prevc = 0;
// byte index = 0;
uint8_t fx_idx ;
byte dataLen;
uint8_t buffer[10];
// Param for different pixel layouts
const bool    kMatrixSerpentineLayout = true;


uint16_t XY( uint8_t x, uint8_t y)
{
  uint16_t i;
  
  if( kMatrixSerpentineLayout == false) {
    i = (y * kMatrixWidth) + x;
  }

  if( kMatrixSerpentineLayout == true) {
    if( y & 0x01) {
      // Odd rows run backwards
      uint8_t reverseX = (kMatrixWidth - 1) - x;
      i = (y * kMatrixWidth) + reverseX;
    } else {
      // Even rows run forwards
      i = (y * kMatrixWidth) + x;
    }
  }
  
  return i;
}

// were supplied.

CRGB leds_plus_safety_pixel[ NUM_LEDS + 1];
CRGB* const leds( leds_plus_safety_pixel + 1);

uint16_t XYsafe( uint8_t x, uint8_t y)
{
  if( x >kMatrixWidth) return -1;
  if( y > kMatrixHeight) return -1;
  return XY(x,y);
}

void parseData()
{
    //f0 55 08 00 02 e0 03 03 ff 00 00
    int cmd = buffer[2];
    if (buffer[0]==0xf0&&buffer[1]==0x55)
    {
       switch (cmd)
        {
            case TARGET_LED://E0
            {   
                 //Serial.println("in set xy and rgb");
                 uint8_t x = buffer[3];
                 uint8_t y = buffer[4];
                 uint8_t r = buffer[5];
                 uint8_t g = buffer[6];
                 uint8_t b = buffer[7];
                 leds[XY(x,y)] = CRGB(r,g,b);
            }
            break;
            case CLEAR://E1
            {    
                //Serial.println("in clear all leds");
                if (buffer[3]==1)
                    {
                        FastLED.clear();
                    }
                 
            }
            break;
            case SOLID://E2
            {
                 //Serial.println("in fill_solid leds");
                 uint8_t r = buffer[3];
                 uint8_t g = buffer[4];
                 uint8_t b = buffer[5];
                 fill_solid( leds, NUM_LEDS, CRGB(r,g,b));
            }
            break;
            case GBRIGHTNESS://E2
            {
                 //Serial.println("in fill_solid leds");
                 uint8_t BR = buffer[3];

                 FastLED.setBrightness( BR );
                 //fill_solid( leds, NUM_LEDS, CRGB(r,g,b));
            }
            break;
        } 
    }       
}

void DrawOneFrame( byte startHue8, int8_t yHueDelta8, int8_t xHueDelta8)
{
  byte lineStartHue = startHue8;
  for( byte y = 0; y < kMatrixHeight; y++) {
    lineStartHue += yHueDelta8;
    byte pixelHue = lineStartHue;      
    for( byte x = 0; x < kMatrixWidth; x++) {
      pixelHue += xHueDelta8;
      leds[ XY(x, y)]  = CHSV( pixelHue, pixelHue, pixelHue);
    }
  }
}
// Demo that USES "XY" follows code below
void setup() {
  delay(5000);
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
  FastLED.setBrightness( BRIGHTNESS );
  Serial.begin(115200);

 

  // FastLED.setBrightness(BRIGHTNESS);
}
 #define TIMEOUT 3000;
void loop()
{
    // readSerial();
    // if (isAvailable)
    // {
    //     read_serial();
    // }
    // #ifndef(__AVR_ATmega2560__)
     Serial.readBytes(buffer, 10);  
    // #endif
    parseData();  
    FastLED.show();// memcpy(buffer,0,20);
    memcpy(buffer,0,10);
}







